package com.yx.changdao.web.controller;

import com.yx.changdao.common.annotation.AutoLog;
import com.yx.changdao.common.data.RespCodeEnum;
import com.yx.changdao.common.data.Result;
import com.yx.changdao.common.entity.SysUser;
import com.yx.changdao.common.exception.AlertException;
import com.yx.changdao.common.utils.*;
import com.yx.changdao.service.SysUserRoleService;
import com.yx.changdao.service.SysUserService;
import com.yx.changdao.web.config.shiro.token.LoginToken;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AccountException;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.subject.Subject;
import org.hibernate.validator.constraints.Length;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @Description: <br/>
 * 登录接口
 * <p>
 * <br/>
 * @Auther: zhangqi
 * @create 2019/11/6 9:03
 */
@Validated
@RestController
// 设置字符集
@RequestMapping(produces = {"application/json;charset=UTF-8"})
public class LoginController {

    /**
     * 用户服务
     */
    @Autowired
    private SysUserService sysUserService;

    /**
     * 用户角色服务
     */
    @Autowired
    private SysUserRoleService sysUserRoleService;


//    @Value("${jwt.time}")
//    private Integer time;

    /**
     * 登录验证码缓存前缀
     */
    public static final String VERIFICATION_FIX = "LOGIN_VERIFICATION_";

    /*@AutoLog
    @PostMapping(value = "/login")
    public Result login(
            @Valid SysUser sysUser,
            // 需要验证码  required  改为true
            @Length(min = 6, max = 6, message = "请输入6位验证码")
            @RequestParam(value = "verification", required = false) String verification,
            HttpServletResponse response) throws AlertException {
        Subject subject = SecurityUtils.getSubject();
        try {
            // 将用户请求参数封装后，直接提交给Shiro处理
            LoginToken loginToken = new LoginToken(sysUser.getUsername(), sysUser.getPassword().toCharArray());
            subject.login(loginToken);

            // shiro认证通过后会将user信息放到subject内，生成token并返回
            SysUser user = (SysUser) subject.getPrincipal();

            if (user.getStatus() == 0) {
                throw new AlertException("用户已锁定");
            }

            String newToken = this.sysUserService.generateJwtToken(user);
            response.setHeader(SysConst.HEAD_TOKEN, newToken);

            Result result = Result.ok("登录成功");

            user.setSalt(null);
            user.setPassword(null);
            user.setDeleteFlag(null);

            Map<String, Object> map = new LinkedHashMap<>();

            map.put("user", ParseDictUtils.parseItem(user));
            map.put("roles", this.sysUserRoleService.getUserRoleIds(user.getUserId()));
            map.put("permissions", this.sysUserRoleService.getUserPermissionIds(user.getUserId()));

            // 用户信息
            result.data(map);

            return result;
        } catch (AuthenticationException e) {
            // 如果校验失败，shiro会抛出异常，返回客户端失败
            e.printStackTrace();
            return Result.error(RespCodeEnum.BAD_REQUEST, "用户名或密码错误");
        }
    }*/


    @AutoLog
    @PostMapping(value = "/login")
    public Result login(@NotBlank(message = "账户名不能为空") @RequestParam("username") String username,
                        @NotBlank(message = "密码不能为空") @RequestParam("password") String password,
                        // 需要验证码  required  改为true
                        @Length(min = 6, max = 6, message = "请输入6位验证码")
                        @RequestParam(value = "verification", required = false) String verification) throws AlertException {
        Subject subject = SecurityUtils.getSubject();
        try {
            // 将用户请求参数封装后，直接提交给Shiro处理
            LoginToken loginToken = new LoginToken(username, password.toCharArray());
            subject.login(loginToken);

            // shiro认证通过后会将user信息放到subject内，生成token并返回
            SysUser user = (SysUser) subject.getPrincipal();
            if (user.getStatus() == 0) {
                throw new AlertException("用户已锁定");
            }
            String newToken = this.sysUserService.generateJwtToken(user);

            Result result = Result.ok("登录成功");
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("authToken",newToken);
            // 用户信息
            result.data(map);
            return result;
        } catch (AuthenticationException e) {
            // 如果校验失败，shiro会抛出异常，返回客户端失败
            e.printStackTrace();
            return Result.error(RespCodeEnum.BAD_REQUEST, "用户名或密码错误");
        }
    }

    @AutoLog
    @PostMapping(value = "/userinfo")
    public Result userInfo(@NotBlank(message = "token不能为空") @RequestParam("token") String token) throws AlertException {
        Result result = Result.ok("用户信息获取成功");
        SysUser user = sysUserService.getJwtTokenInfo(JwtUtils.getJwtload(token).getUserID(), token);
        if (user == null) {
            throw new AccountException("token过期，请重新登录");
        }
        user.setSalt(null);
        user.setPassword(null);
        user.setDeleteFlag(null);

        Map<String, Object> map = new LinkedHashMap<>();
        map.put("user", ParseDictUtils.parseItem(user));
        map.put("roles", this.sysUserRoleService.getUserRoleIds(user.getUserId()));
        map.put("permissions", this.sysUserRoleService.getUserPermissionIds(user.getUserId()));

        // 用户信息
        result.data(map);

        return result;
    }


    @AutoLog
    @GetMapping(value = "/logout")
    public Result logout() {
        this.sysUserService.deleteLoginInfo(SysUtils.currentUserId());
        SecurityUtils.getSubject().logout();
        return Result.ok("退出成功");
    }

}
